#include "SegmentationAlgorithms.h"
#include <QtGui/QMessageBox>

QSegmentationAlgorithmRunner::QSegmentationAlgorithmRunner(QList<QString> list,int type)
{
	this->list=list;
	AlgorithmType=type;
}
QSegmentationAlgorithmRunner::~QSegmentationAlgorithmRunner()
{

}
void QSegmentationAlgorithmRunner::run()
{
	if(AlgorithmType==1)
	{
		typedef   float           InternalPixelType;
		const     unsigned int    Dimension = 2;
		typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;

		typedef unsigned char                            OutputPixelType;
		typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

		typedef itk::BinaryThresholdImageFilter< InternalImageType, 
			OutputImageType    >    ThresholdingFilterType;
		ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();

		const InternalPixelType  timeThreshold = list[7].toDouble();

		// Software Guide : BeginCodeSnippet
		thresholder->SetLowerThreshold(           0.0  );
		thresholder->SetUpperThreshold( timeThreshold  );

		thresholder->SetOutsideValue(  0  );
		thresholder->SetInsideValue(  255 );

		typedef  itk::ImageFileReader< InternalImageType > ReaderType;
		typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;
		// Software Guide : EndCodeSnippet


		ReaderType::Pointer reader = ReaderType::New();
		WriterType::Pointer writer = WriterType::New();

		reader->SetFileName( list[0].toLocal8Bit().data() );
		writer->SetFileName( (list[1]+QString("/FastMarchingOutputImage.png")).toLocal8Bit().data() );

		itemGroup=list[1];
		QString temp=QString(" ")+list[1]+QString("/FastMarchingOutputImage.png");
		itemGroup.append(temp);

		typedef itk::RescaleIntensityImageFilter< 
			InternalImageType, 
			OutputImageType >   CastFilterType;


		typedef   itk::CurvatureAnisotropicDiffusionImageFilter< 
			InternalImageType, 
			InternalImageType >  SmoothingFilterType;

		SmoothingFilterType::Pointer smoothing = SmoothingFilterType::New();

		typedef   itk::GradientMagnitudeRecursiveGaussianImageFilter< 
			InternalImageType, 
			InternalImageType >  GradientFilterType;
		typedef   itk::SigmoidImageFilter<
			InternalImageType, 
			InternalImageType >  SigmoidFilterType;

		GradientFilterType::Pointer  gradientMagnitude = GradientFilterType::New();
		SigmoidFilterType::Pointer sigmoid = SigmoidFilterType::New();

		sigmoid->SetOutputMinimum(  0.0  );
		sigmoid->SetOutputMaximum(  1.0  );

		typedef  itk::FastMarchingImageFilter< InternalImageType, 
			InternalImageType >    FastMarchingFilterType;
		FastMarchingFilterType::Pointer  fastMarching = FastMarchingFilterType::New();

		smoothing->SetInput( reader->GetOutput() );
		gradientMagnitude->SetInput( smoothing->GetOutput() );
		sigmoid->SetInput( gradientMagnitude->GetOutput() );
		fastMarching->SetInput( sigmoid->GetOutput() );
		thresholder->SetInput( fastMarching->GetOutput() );
		writer->SetInput( thresholder->GetOutput() );

		smoothing->SetTimeStep( 0.125 );
		smoothing->SetNumberOfIterations(  5 );
		smoothing->SetConductanceParameter( 9.0 );
		const double sigma = list[4].toDouble();

		// Software Guide : BeginCodeSnippet
		gradientMagnitude->SetSigma(  sigma  );

		const double alpha = list[5].toDouble();
		const double beta  = list[6].toDouble();


		// Software Guide : BeginCodeSnippet
		sigmoid->SetAlpha( alpha );
		sigmoid->SetBeta(  beta  );

		typedef FastMarchingFilterType::NodeContainer           NodeContainer;
		typedef FastMarchingFilterType::NodeType                NodeType;
		NodeContainer::Pointer seeds = NodeContainer::New();
		//  Software Guide : EndCodeSnippet 


		InternalImageType::IndexType  seedPosition;

		seedPosition[0] = list[2].toInt();
		seedPosition[1] = list[3].toInt();

		NodeType node;
		const double seedValue = 0.0;

		node.SetValue( seedValue );
		node.SetIndex( seedPosition );

		seeds->Initialize();
		seeds->InsertElement( 0, node );
		fastMarching->SetTrialPoints(  seeds  );


		CastFilterType::Pointer caster1 = CastFilterType::New();
		CastFilterType::Pointer caster2 = CastFilterType::New();
		CastFilterType::Pointer caster3 = CastFilterType::New();
		CastFilterType::Pointer caster4 = CastFilterType::New();

		WriterType::Pointer writer1 = WriterType::New();
		WriterType::Pointer writer2 = WriterType::New();
		WriterType::Pointer writer3 = WriterType::New();
		WriterType::Pointer writer4 = WriterType::New();

		caster1->SetInput( smoothing->GetOutput() );
		writer1->SetInput( caster1->GetOutput() );
		writer1->SetFileName((list[1]+QString("/FastMarchingFilterOutput1.png")).toLocal8Bit().data());		
		caster1->SetOutputMinimum(   0 );
		caster1->SetOutputMaximum( 255 );
		writer1->Update();
		emit ImageShow(list[1]+QString("/FastMarchingFilterOutput1.png"));
		temp=QString(" ")+list[1]+QString("/FastMarchingFilterOutput1.png");
		itemGroup.append(temp);

		caster2->SetInput( gradientMagnitude->GetOutput() );
		writer2->SetInput( caster2->GetOutput() );
		writer2->SetFileName((list[1]+QString("/FastMarchingFilterOutput2.png")).toLocal8Bit().data());		
		caster2->SetOutputMinimum(   0 );
		caster2->SetOutputMaximum( 255 );
		writer2->Update();
		emit ImageShow(list[1]+QString("/FastMarchingFilterOutput2.png"));
		temp=QString(" ")+list[1]+QString("/FastMarchingFilterOutput2.png");
		itemGroup.append(temp);

		caster3->SetInput( sigmoid->GetOutput() );
		writer3->SetInput( caster3->GetOutput() );
		writer3->SetFileName((list[1]+QString("/FastMarchingFilterOutput3.png")).toLocal8Bit().data());
		caster3->SetOutputMinimum(   0 );
		caster3->SetOutputMaximum( 255 );
		writer3->Update();
		emit ImageShow(list[1]+QString("/FastMarchingFilterOutput3.png"));
		temp=QString(" ")+list[1]+QString("/FastMarchingFilterOutput3.png");
		itemGroup.append(temp);

		caster4->SetInput( fastMarching->GetOutput() );
		writer4->SetInput( caster4->GetOutput() );
		writer4->SetFileName((list[1]+QString("/FastMarchingFilterOutput4.png")).toLocal8Bit().data());
		caster4->SetOutputMinimum(   0 );
		caster4->SetOutputMaximum( 255 );


		fastMarching->SetOutputSize( 
			reader->GetOutput()->GetBufferedRegion().GetSize() );

		const double stoppingTime = list[8].toDouble();

		// Software Guide : BeginCodeSnippet
		fastMarching->SetStoppingValue(  stoppingTime  );

		try
		{
			writer->Update();
		}
		catch( itk::ExceptionObject & excep )
		{
			std::cerr << "Exception caught !" << std::endl;
			std::cerr << excep << std::endl;
		}

		writer4->Update();
		emit ImageShow(list[1]+QString("/FastMarchingFilterOutput4.png"));
		temp=QString(" ")+list[1]+QString("/FastMarchingFilterOutput4.png");
		itemGroup.append(temp);
		emit ImageShow(list[1]+QString("/FastMarchingOutputImage.png"));		
		typedef itk::ImageFileWriter< InternalImageType > InternalWriterType;

		InternalWriterType::Pointer mapWriter = InternalWriterType::New();
		mapWriter->SetInput( fastMarching->GetOutput() );
		mapWriter->SetFileName((list[1]+QString("/FastMarchingFilterOutput4.mha")).toLocal8Bit().data());
		mapWriter->Update();

		InternalWriterType::Pointer speedWriter = InternalWriterType::New();
		speedWriter->SetInput( sigmoid->GetOutput() );
		speedWriter->SetFileName((list[1]+QString("/FastMarchingFilterOutput3.mha")).toLocal8Bit().data());
		speedWriter->Update();

		InternalWriterType::Pointer gradientWriter = InternalWriterType::New();
		gradientWriter->SetInput( gradientMagnitude->GetOutput() );
		gradientWriter->SetFileName((list[1]+QString("/FastMarchingFilterOutput2.mha")).toLocal8Bit().data());
		gradientWriter->Update();
		emit FillItem(itemGroup);
		//emit over();
		
	}
}